import { Node, Layers, Sprite, sp, director, instantiate, Label, Color } from 'cc';
import { ResourceManager } from '../managers/ResourceManager';
import { GlobalRoot } from '../global/GlobalRoot';

/**
 * ResourceManager 功能测试用例集合
 * 包含本地、bundle、远程、预加载等所有核心功能测试
 */
export class ResourceManagerTest {
    /**
     * 运行所有测试用例
     */
    static runAll(parentNode?: Node) {
        this.testLocalSingleImage(parentNode);
        this.testLocalAtlasImage(parentNode);
        this.testBundleSingleImage(parentNode);
        this.testBundleAtlasImage(parentNode);
        this.testLocalFramesAtlas(parentNode);
        this.testLocalFramesScatter(parentNode);
        this.testLocalSpine(parentNode);
        this.testBundleFramesAtlas(parentNode);
        this.testBundleFramesScatter(parentNode);
        this.testRemoteSingleImage(parentNode);
        this.testRemoteFramesScatter(parentNode);
        this.testRemoteSpine(parentNode);
        this.testPreloadImg(parentNode);
        this.testPreloadFrames(parentNode);
        this.testPreloadSpine(parentNode);
        this.testPreloadPrefab(parentNode);
        this.testPreloadJson(parentNode);
    }

    /**
     * 测试本地resources目录下的单张图片加载
     * 预期：节点上能正常显示图片，控制台输出SpriteFrame对象
     */
    static testLocalSingleImage(parentNode?: Node) {
        const node = new Node('ResImgSingle');
        node.layer = Layers.Enum.UI_2D;
        node.setPosition(0, 0, 0);
        const sprite = node.addComponent(Sprite);
        ResourceManager.instance.loadImg(node, { name: "test/img/f_1" }, (sf) => {
            console.log("[测试] resources单张图片加载完成", sf);
            GlobalRoot.instance.UiManager.showTips("[测试] resources单张图片加载完成")
        });
        this._addToParentOrCanvas(node, parentNode);
    }
    /**
     * 测试本地resources目录下的合图图片加载
     * 预期：节点上能正常显示合图中的指定帧
     */
    static testLocalAtlasImage(parentNode?: Node) {
        const node = new Node('ResImgAtlas');
        node.layer = Layers.Enum.UI_2D;
        node.setPosition(0, 0, 0);
        const sprite = node.addComponent(Sprite);
        ResourceManager.instance.loadImg(node, { name: "test/img/allF", frame: "f_1" }, (sf) => {
            console.log("[测试] resources合图图片加载完成", sf);
            GlobalRoot.instance.UiManager.showTips("[测试] resources合图图片加载完成")

        });
        this._addToParentOrCanvas(node, parentNode);
    }
    /**
     * 测试bundle下的单张图片加载
     * 预期：节点上能正常显示bundle中的图片
     */
    static testBundleSingleImage(parentNode?: Node) {
        const node = new Node('BundleImgSingle');
        node.layer = Layers.Enum.UI_2D;
        node.setPosition(0, 0, 0);
        const sprite = node.addComponent(Sprite);
        ResourceManager.instance.loadImg(node, { name: "img/f_1", bundle: "testDemo" }, (sf) => {
            console.log("[测试] testDemo单张图片加载完成", sf);
            GlobalRoot.instance.UiManager.showTips("[测试] testDemo单张图片加载完成")

        });
        this._addToParentOrCanvas(node, parentNode);
    }
    /**
     * 测试bundle下的合图图片加载
     * 预期：节点上能正常显示bundle合图中的指定帧
     */
    static testBundleAtlasImage(parentNode?: Node) {
        const node = new Node('BundleImgAtlas');
        node.layer = Layers.Enum.UI_2D;
        node.setPosition(0, 0, 0);
        const sprite = node.addComponent(Sprite);
        ResourceManager.instance.loadImg(node, { name: "img/allF", frame: "f_1", bundle: "testDemo" }, (sf) => {
            console.log("[测试] testDemo合图图片加载完成", sf);
            GlobalRoot.instance.UiManager.showTips("[测试] testDemo合图图片加载完成")

        });
        this._addToParentOrCanvas(node, parentNode);
    }
    /**
     * 测试本地resources目录下的合图序列帧动画
     * 预期：节点上能正常播放合图序列帧动画
     */
    static testLocalFramesAtlas(parentNode?: Node) {
        const node = new Node('ResFramesAtlas');
        node.layer = Layers.Enum.UI_2D;
        node.setPosition(0, 0, 0);
        ResourceManager.instance.playFrames({
            node,
            name: "test/frams/guai-qw_walk",
            fps: 12,
            loop: true,
            onStart: () => {
                console.log("[测试] resources合图序列帧动画开始");
                GlobalRoot.instance.UiManager.showTips("[测试] resources合图序列帧动画开始")

            },
            onEnd: () => {
                console.log("[测试] resources合图序列帧动画结束");
                GlobalRoot.instance.UiManager.showTips("[测试] resources合图序列帧动画结束")

            }
        });
        this._addToParentOrCanvas(node, parentNode);
    }
    /**
     * 测试本地resources目录下的散图序列帧动画
     * 预期：节点上能正常播放散图序列帧动画
     */
    static testLocalFramesScatter(parentNode?: Node) {
        const node = new Node('ResFramesScatter');
        node.layer = Layers.Enum.UI_2D;
        node.setPosition(0, 0, 0);
        ResourceManager.instance.playFrames({
            node,
            name: "test/frams/guai-qw_walk_0",
            pattern: "test/frams/guai-qw_walk_{i}",
            count: 8,
            fps: 12,
            loop: true,
            onStart: () => {
                GlobalRoot.instance.UiManager.showTips("[测试] resources散图序列帧动画开始")
                console.log("[测试] resources散图序列帧动画开始");
            },
            onEnd: () => {
                GlobalRoot.instance.UiManager.showTips("[测试] resources散图序列帧动画结束")

                console.log("[测试] resources散图序列帧动画结束");
            }
        });
        this._addToParentOrCanvas(node, parentNode);
    }
    /**
     * 测试本地resources目录下的spine动画
     * 预期：节点上能正常显示spine动画，且可设置动画名和循环
     */
    static testLocalSpine(parentNode?: Node) {
        const node = new Node('ResSpine');
        node.layer = Layers.Enum.UI_2D;
        node.setPosition(0, 0, 0);
        ResourceManager.instance.loadSpine(node, { name: "test/spine/dongwu" }, "1", true, (sk) => {
            console.log("[测试] resources spine动画加载完成", sk);
            node.getComponent(sp.Skeleton).premultipliedAlpha = false;
            GlobalRoot.instance.UiManager.showTips("[测试] resources spine动画加载完成")

        });
        this._addToParentOrCanvas(node, parentNode);
    }
    /**
     * 测试bundle下的合图序列帧动画
     * 预期：节点上能正常播放bundle合图序列帧动画
     */
    static testBundleFramesAtlas(parentNode?: Node) {
        const node = new Node('BundleFramesAtlas');
        node.layer = Layers.Enum.UI_2D;
        node.setPosition(0, 0, 0);
        ResourceManager.instance.playFrames({
            node,
            name: "frams/guai-qw_walk",
            bundle: "testDemo",
            fps: 12,
            loop: true,
            onStart: () => { console.log("[测试] bundle合图序列帧动画开始"); },
            onEnd: () => {
                console.log("[测试] bundle合图序列帧动画结束");
                GlobalRoot.instance.UiManager.showTips("[测试] bundle合图序列帧动画结束")

            }
        });
        this._addToParentOrCanvas(node, parentNode);
    }
    /**
     * 测试bundle下的散图序列帧动画
     * 预期：节点上能正常播放bundle散图序列帧动画
     */
    static testBundleFramesScatter(parentNode?: Node) {
        const node = new Node('BundleFramesScatter');
        node.layer = Layers.Enum.UI_2D;
        node.setPosition(0, 0, 0);
        ResourceManager.instance.playFrames({
            node,
            name: "frams/guai-qw_walk_0",
            pattern: "frams/guai-qw_walk_{i}",
            count: 8,
            bundle: "testDemo",
            fps: 12,
            loop: true,
            onStart: () => { console.log("[测试] bundle散图序列帧动画开始"); },
            onEnd: () => {
                console.log("[测试] bundle散图序列帧动画结束");
                GlobalRoot.instance.UiManager.showTips("[测试] bundle散图序列帧动画结束")

            }
        });
        this._addToParentOrCanvas(node, parentNode);
    }
    /**
     * 测试远程单张图片加载
     * 预期：节点上能正常显示远程图片
     */
    static testRemoteSingleImage(parentNode?: Node) {
        const node = new Node('TestImgSingleRemote');
        node.layer = Layers.Enum.UI_2D;
        node.setPosition(0, 0, 0);
        const sprite = node.addComponent(Sprite);
        ResourceManager.instance.loadImg(node, { name: "testDemo/img/f_1", remote: true }, (sf) => {
            console.log("[测试] 远程单张图片加载完成", sf);
            GlobalRoot.instance.UiManager.showTips("[测试] 远程单张图片加载完成")

        });
        this._addToParentOrCanvas(node, parentNode);
    }
    /**
     * 测试远程散图序列帧动画
     * 预期：节点上能正常播放远程散图序列帧动画
     */
    static testRemoteFramesScatter(parentNode?: Node) {
        const node = new Node('TestFramesScatterRemote');
        node.layer = Layers.Enum.UI_2D;
        node.setPosition(0, 0, 0);
        ResourceManager.instance.playFrames({
            node,
            name: "testDemo/frams/guai-qw_walk_0",
            pattern: "testDemo/frams/guai-qw_walk_{i}",
            count: 8,
            remote: true,
            fps: 12,
            loop: true,
            onStart: () => { console.log("[测试] 远程散图序列帧动画开始"); },
            onEnd: () => { console.log("[测试] 远程散图序列帧动画结束");
            GlobalRoot.instance.UiManager.showTips("[测试] 远程散图序列帧动画结束")

             }
        });
        this._addToParentOrCanvas(node, parentNode);
    }
    /**
     * 测试远程spine动画
     * 预期：节点上能正常显示远程spine动画
     */
    static testRemoteSpine(parentNode?: Node) {
        const node = new Node('TestSpineRemote');
        node.layer = Layers.Enum.UI_2D;
        node.setPosition(0, 0, 0);
        ResourceManager.instance.loadSpine(node, { name: "testDemo/spine/dongwu", remote: true }, "1", true, (sk) => {
            console.log("[测试] 远程spine动画加载完成", sk);
            node.getComponent(sp.Skeleton).premultipliedAlpha = false;
            GlobalRoot.instance.UiManager.showTips("[测试] 远程spine动画加载完成")

        });
        this._addToParentOrCanvas(node, parentNode);
    }
    /**
     * 测试预加载单张图片
     * 预期：预加载后可秒加载显示
     */
    static testPreloadImg(parentNode?: Node) {
        ResourceManager.instance.preloadImg({ name: "test/img/f_1" }, (sf) => {
            console.log("[测试] 预加载图片完成", sf);
            if (parentNode) {
                parentNode.removeAllChildren();
                const labelNode = new Node("ImgLabel");
                labelNode.layer = Layers.Enum.UI_2D;
                const label = labelNode.addComponent(Label);
                label.overflow = Label.Overflow.RESIZE_HEIGHT;
                label.lineHeight = 24;
                label.fontSize = 18;
                label.string = "预加载图片完成: " + (sf ? "成功" : "失败");
                labelNode.setPosition(0, 0);
                parentNode.addChild(labelNode);
            }
            GlobalRoot.instance.UiManager.showTips("[测试] 预加载图片完成")

        });
    }
    /**
     * 测试预加载序列帧
     * 预期：预加载后可秒加载显示动画
     */
    static testPreloadFrames(parentNode?: Node) {
        ResourceManager.instance.preloadFrames({ name: "test/frams/guai-qw_walk" }, (frames) => {
            console.log("[测试] 预加载序列帧完成", frames);
            if (parentNode) {
                parentNode.removeAllChildren();
                const labelNode = new Node("FramesLabel");
                labelNode.layer = Layers.Enum.UI_2D;
                const label = labelNode.addComponent(Label);
                label.overflow = Label.Overflow.RESIZE_HEIGHT;
                label.lineHeight = 24;
                label.fontSize = 18;
                label.string = "预加载序列帧完成: " + (frames && frames.length ? "成功" : "失败");
                labelNode.setPosition(0, 0);
                parentNode.addChild(labelNode);
            }
            GlobalRoot.instance.UiManager.showTips("[测试] 预加载序列帧完成")

        });
    }
    /**
     * 测试预加载spine动画
     * 预期：预加载后可秒加载显示spine动画
     */
    static testPreloadSpine(parentNode?: Node) {
        ResourceManager.instance.preloadSpine({ name: "test/spine/dongwu" }, (sk) => {
            console.log("[测试] 预加载Spine完成", sk);
            if (parentNode) {
                parentNode.removeAllChildren();
                const labelNode = new Node("SpineLabel");
                labelNode.layer = Layers.Enum.UI_2D;
                const label = labelNode.addComponent(Label);
                label.overflow = Label.Overflow.RESIZE_HEIGHT;
                label.lineHeight = 24;
                label.fontSize = 18;
                label.string = "预加载Spine完成: " + (sk ? "成功" : "失败");
                labelNode.setPosition(0, 0);
                parentNode.addChild(labelNode);
            }
            GlobalRoot.instance.UiManager.showTips("[测试] 预加载Spine完成")

        });
    }
    /**
     * 测试预加载Prefab
     * 预期：预加载后可秒实例化显示
     */
    static testPreloadPrefab(parentNode?: Node) {
        ResourceManager.instance.preloadPrefab({ name: "prefab/blockLayer" }, (prefab) => {
            console.log("[测试] 预加载Prefab完成", prefab);
            if (parentNode) {
                parentNode.removeAllChildren();
                const labelNode = new Node("PrefabLabel");
                labelNode.layer = Layers.Enum.UI_2D;
                const label = labelNode.addComponent(Label);
                label.overflow = Label.Overflow.RESIZE_HEIGHT;
                label.lineHeight = 24;
                label.fontSize = 18;
                label.string = "预加载Prefab完成: " + (prefab ? "成功" : "失败");
                labelNode.setPosition(0, 0);
                parentNode.addChild(labelNode);
            }
            GlobalRoot.instance.UiManager.showTips("[测试] 预加载Prefab完成")

        });
    }
    /**
     * 测试预加载Json
     * 预期：预加载后可秒获取配置数据
     */
    static testPreloadJson(parentNode?: Node) {
        ResourceManager.instance.preloadJson({ name: "config/system" }, (json) => {
            console.log("[测试] 预加载Json完成", json);
            if (parentNode) {;
                parentNode.removeAllChildren();
                const labelNode = new Node("JsonLabel");
                labelNode.layer = Layers.Enum.UI_2D;
                const label = labelNode.addComponent(Label);
                label.overflow = Label.Overflow.RESIZE_HEIGHT;
                label.lineHeight = 24;
                label.fontSize = 18;
                label.string = JSON.stringify(json, null, 2);
                labelNode.setPosition(0, 0);
                label.color = Color.RED
                parentNode.addChild(labelNode);
            }
            GlobalRoot.instance.UiManager.showTips("[测试] 预加载Prefab完成")

        });
    }

    /**
     * 工具：将测试节点添加到Canvas
     */
    private static _addToCanvas(node: Node) {
        const canvas = director.getScene().getChildByName("Canvas");
        if (canvas) {
            node.parent = canvas;
        } else {
            node.parent = director.getScene();
        }
    }

    private static _addToParentOrCanvas(node: Node, parentNode?: Node) {
        if (parentNode) {
            parentNode.addChild(node);
        } else {
            this._addToCanvas(node);
        }
    }
} 